From 93dcb1dab57c6d53ff3ab6832cf1f5ed7039dc86 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Tue, 23 Jan 2007 09:08:03 -0700 Subject: [PATCH] [IA64] Avoid dom0 insufficient memory panic when creating guests When there is not enough memory to create a domain, we need not panic domain0. Just prevent it from creating. Signed-off-by: Zhang Xin --- xen/arch/ia64/vmx/vmmu.c | 39 +++++++++++++++++++++++++++--------- xen/arch/ia64/vmx/vmx_init.c | 7 +++++-- xen/arch/ia64/xen/domain.c | 8 +++++--- xen/include/asm-ia64/vmmu.h | 2 +- xen/include/asm-ia64/vmx.h | 2 +- 5 files changed, 42 insertions(+), 16 deletions(-) diff --git a/xen/arch/ia64/vmx/vmmu.c b/xen/arch/ia64/vmx/vmmu.c index aaf4055674..145cd4c447 100644 --- a/xen/arch/ia64/vmx/vmmu.c +++ b/xen/arch/ia64/vmx/vmmu.c @@ -129,13 +129,15 @@ purge_machine_tc_by_domid(domid_t domid) #endif } -static void init_domain_vhpt(struct vcpu *v) +static int init_domain_vhpt(struct vcpu *v) { struct page_info *page; void * vbase; page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0); if ( page == NULL ) { - panic_domain(vcpu_regs(v),"No enough contiguous memory for init_domain_vhpt\n"); + printk("No enough contiguous memory for init_domain_vhpt\n"); + + return -1; } vbase = page_to_virt(page); memset(vbase, 0, VCPU_VHPT_SIZE); @@ -147,18 +149,36 @@ static void init_domain_vhpt(struct vcpu *v) VHPT(v,cch_sz) = VCPU_VHPT_SIZE - VHPT(v,hash_sz); thash_init(&(v->arch.vhpt),VCPU_VHPT_SHIFT-1); v->arch.arch_vmx.mpta = v->arch.vhpt.pta.val; + + return 0; } +static void free_domain_vhpt(struct vcpu *v) +{ + struct page_info *page; -void init_domain_tlb(struct vcpu *v) + if (v->arch.vhpt.hash) { + page = virt_to_page(v->arch.vhpt.hash); + free_domheap_pages(page, VCPU_VHPT_ORDER); + } + + return; +} + +int init_domain_tlb(struct vcpu *v) { struct page_info *page; void * vbase; - init_domain_vhpt(v); + + if (init_domain_vhpt(v) != 0) + return -1; + page = alloc_domheap_pages (NULL, VCPU_VTLB_ORDER, 0); if ( page == NULL ) { - panic_domain(vcpu_regs(v),"No enough contiguous memory for init_domain_tlb\n"); + printk("No enough contiguous memory for init_domain_tlb\n"); + free_domain_vhpt(v); + return -1; } vbase = page_to_virt(page); memset(vbase, 0, VCPU_VTLB_SIZE); @@ -169,8 +189,11 @@ void init_domain_tlb(struct vcpu *v) VTLB(v,cch_buf) = (void *)((u64)vbase + VTLB(v,hash_sz)); VTLB(v,cch_sz) = VCPU_VTLB_SIZE - VTLB(v,hash_sz); thash_init(&(v->arch.vtlb),VCPU_VTLB_SHIFT-1); + + return 0; } + void free_domain_tlb(struct vcpu *v) { struct page_info *page; @@ -179,10 +202,8 @@ void free_domain_tlb(struct vcpu *v) page = virt_to_page(v->arch.vtlb.hash); free_domheap_pages(page, VCPU_VTLB_ORDER); } - if ( v->arch.vhpt.hash) { - page = virt_to_page(v->arch.vhpt.hash); - free_domheap_pages(page, VCPU_VHPT_ORDER); - } + + free_domain_vhpt(v); } /* diff --git a/xen/arch/ia64/vmx/vmx_init.c b/xen/arch/ia64/vmx/vmx_init.c index c4cb0150ea..2ae82ed086 100644 --- a/xen/arch/ia64/vmx/vmx_init.c +++ b/xen/arch/ia64/vmx/vmx_init.c @@ -290,7 +290,7 @@ static void vmx_release_assist_channel(struct vcpu *v) * Initialize VMX envirenment for guest. Only the 1st vp/vcpu * is registered here. */ -void +int vmx_final_setup_guest(struct vcpu *v) { vpd_t *vpd; @@ -305,7 +305,8 @@ vmx_final_setup_guest(struct vcpu *v) * to this solution. Maybe it can be deferred until we know created * one as vmx domain */ #ifndef HASH_VHPT - init_domain_tlb(v); + if (init_domain_tlb(v) != 0) + return -1; #endif vmx_create_event_channels(v); @@ -322,6 +323,8 @@ vmx_final_setup_guest(struct vcpu *v) /* Set up guest 's indicator for VTi domain*/ set_bit(ARCH_VMX_DOMAIN, &v->arch.arch_vmx.flags); + + return 0; } void diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index dc4ead671f..c0b00e83d3 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -585,9 +585,11 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) if (test_bit(_VCPUF_initialised, &v->vcpu_flags)) return 0; - if (d->arch.is_vti) - vmx_final_setup_guest(v); - else { + if (d->arch.is_vti) { + rc = vmx_final_setup_guest(v); + if (rc != 0) + return rc; + } else { rc = vcpu_late_initialise(v); if (rc != 0) return rc; diff --git a/xen/include/asm-ia64/vmmu.h b/xen/include/asm-ia64/vmmu.h index 4b86a33711..9c436ce0e6 100644 --- a/xen/include/asm-ia64/vmmu.h +++ b/xen/include/asm-ia64/vmmu.h @@ -295,7 +295,7 @@ extern u64 machine_thash(PTA pta, u64 va); extern void purge_machine_tc_by_domid(domid_t domid); extern void machine_tlb_insert(struct vcpu *d, thash_data_t *tlb); extern ia64_rr vmmu_get_rr(struct vcpu *vcpu, u64 va); -extern void init_domain_tlb(struct vcpu *d); +extern int init_domain_tlb(struct vcpu *d); extern void free_domain_tlb(struct vcpu *v); extern thash_data_t * vsa_thash(PTA vpta, u64 va, u64 vrr, u64 *tag); extern thash_data_t * vhpt_lookup(u64 va); diff --git a/xen/include/asm-ia64/vmx.h b/xen/include/asm-ia64/vmx.h index 4e0971278a..5cd0e8c9bf 100644 --- a/xen/include/asm-ia64/vmx.h +++ b/xen/include/asm-ia64/vmx.h @@ -31,7 +31,7 @@ extern void identify_vmx_feature(void); extern unsigned int vmx_enabled; extern void vmx_init_env(void); -extern void vmx_final_setup_guest(struct vcpu *v); +extern int vmx_final_setup_guest(struct vcpu *v); extern void vmx_save_state(struct vcpu *v); extern void vmx_load_state(struct vcpu *v); extern void vmx_setup_platform(struct domain *d); -- 2.30.2